#[derive(Debug, PartialEq, Clone)]
pub enum Ast {
    /// A block of statements, often a function body or loop body.
    Block(Vec<Ast>),
    /// Assignment: `name = value`
    Assignment {
        name: String,
        value: Box<Ast>,
    },
    /// A binary operation: `lhs op rhs`
    BinaryOp {
        op: Op,
        lhs: Box<Ast>,
        rhs: Box<Ast>,
    },
    /// A number literal.
    Number(f64),
    /// A string literal.
    String(String),
    /// An identifier (variable or function name).
    Identifier(String),
    /// A matrix literal: `[1 2; 3 4]`
    Matrix(Vec<Vec<Ast>>),
    /// A conditional statement: `if cond ... end`
    IfStatement {
        cond: Box<Ast>,
        body: Box<Ast>,
    },
    /// A loop statement: `for var = range ... end`
    ForLoop {
        var: String,
        range: Box<Ast>,
        body: Box<Ast>,
    },
}

#[derive(Debug, PartialEq, Clone)]
pub enum Op {
    Add, Sub, Mul, Div,
    Eq, Ne, Gt, Lt, Ge, Le,
}